/*
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         佛祖保佑       永无BUG


* @文件说明：

* @修改记录：2021/05/13
*/

/*Includes ----------------------------------------------*/
#include "b_drv_pca9557.h"
/**
 * \addtogroup B_DRIVER
 * \{
 */

/**
 * \addtogroup  PCA9557
 * \{
 */

/**
 * \defgroup  PCA9557_Private_TypesDefinitions
 * \{
 */

/**
 * \}
 */

/**
 * \defgroup  PCA9557_Private_Defines
 * \{
 */

/**
 * \}
 */

/**
 * \defgroup  PCA9557_Private_Macros
 * \{
 */
#define PCA9557_REG_IN 0
#define PCA9557_REG_OUT 1
#define PCA9557_REG_POLARITY_INVERSION 2
#define PCA9557_REG_CONFIG 3
/**
 * \}
 */

/**
 * \defgroup  PCA9557_Private_Variables
 * \{
 */
b_pca9557_halif_t  b_pca9557_halif[] = PCA9557_HALIF_CONFIG;
b_pca9557_driver_t b_pca9557_driver[sizeof(b_pca9557_halif) / sizeof(b_pca9557_halif_t)];
/**
 * \}
 */

/**
 * \defgroup  PCA9557_Private_FunctionPrototypes
 * \{
 */

/**
 * \}
 */

/**
 * \defgroup  PCA9557_Private_Functions
 * \{
 */

static int _b_pca9557_config(b_pca9557_driver_t *pdrv, uint32_t off, uint8_t data)
{
    // b_log("_b_pca9557_config off %d, data %d\r\n", off, data);
    if (off >= 8)
    {
        return -1;
    }
    uint8_t            tmp;
    b_pca9557_halif_t *hal_if = pdrv->_hal_if;

    if (bHalI2C_MemRead(hal_if->i2c, hal_if->dev_addr, PCA9557_REG_CONFIG, &tmp, 1) < 0)
    {

        return -1;
    }

    // b_log("_b_pca9557_config tmp %d\r\n", tmp);
    if (data)
    {
        tmp |= 1 << off;
    }
    else
    {
        tmp &= ~(1 << off);
    }
    return bHalI2C_MemWrite(hal_if->i2c, hal_if->dev_addr, PCA9557_REG_CONFIG, &tmp, 1);
}

static int _b_pca9557_write(b_pca9557_driver_t *pdrv, uint32_t off, uint8_t *pbuf, uint16_t len)
{
    if (off >= 8 || len != 1)
    {
        return -1;
    }

    b_pca9557_halif_t *hal_if = pdrv->_hal_if;

    if (pbuf[0])
    {
        pdrv->_private.v |= 1 << off;
    }
    else
    {
        pdrv->_private.v &= ~(1 << off);
    }
    uint8_t tmp = pdrv->_private.v;
    bHalI2C_MemWrite(hal_if->i2c, hal_if->dev_addr, PCA9557_REG_OUT, &tmp, 1);
    return len;
}

static int _b_pca9557_read(b_pca9557_driver_t *pdrv, uint32_t off, uint8_t *pbuf, uint16_t len)
{
    uint8_t            tmp;
    b_pca9557_halif_t *hal_if = pdrv->_hal_if;
    if (off >= 8 || len != 1)
    {
        return -1;
    }

    bHalI2C_MemRead(hal_if->i2c, hal_if->dev_addr, PCA9557_REG_IN, &tmp, 1);
    if (tmp & (1 << off))
    {
        pbuf[0] = 1;
    }
    else
    {
        pbuf[0] = 0;
    }
    return len;
}

static int _b_pca9557_ctrl(b_pca9557_driver_t *pdrv, uint8_t cmd, void *param)
{
    b_pca9557_halif_t *hal_if    = pdrv->_hal_if;
    b_cmd_io_t *       cmd_param = param;
    switch (cmd)
    {
        case bCMD_IO_CONFIG:
            _b_pca9557_config(pdrv, cmd_param->offset, cmd_param->data);
            break;
        case bCMD_IO_WRITE_ALL:
            bHalI2C_MemWrite(hal_if->i2c, hal_if->dev_addr, PCA9557_REG_OUT, param, 1);
            break;
        case bCMD_IO_READ_ALL:
            bHalI2C_MemRead(hal_if->i2c, hal_if->dev_addr, PCA9557_REG_IN, param, 1);
            break;
        default:
            break;
    }
    return 0;
}

/**
 * \}
 */

/**
 * \addtogroup  PCA9557_Exported_Functions
 * \{
 */
int b_pca9557_init()
{
    uint8_t i;
    for (i = 0; i < sizeof(b_pca9557_halif) / sizeof(b_pca9557_halif_t); i++)
    {
        b_pca9557_driver[i].status  = 0;
        b_pca9557_driver[i].close   = NULL;
        b_pca9557_driver[i].read    = _b_pca9557_read;
        b_pca9557_driver[i].ctl     = _b_pca9557_ctrl;
        b_pca9557_driver[i].open    = NULL;
        b_pca9557_driver[i].write   = _b_pca9557_write;
        b_pca9557_driver[i]._hal_if = &b_pca9557_halif[i];
        uint8_t data                = 0;
        bHalI2C_MemWrite(b_pca9557_halif[i].i2c, b_pca9557_halif[i].dev_addr,
                         PCA9557_REG_POLARITY_INVERSION, &data, 1);
        data = 0xff;
        bHalI2C_MemWrite(b_pca9557_halif[i].i2c, b_pca9557_halif[i].dev_addr, PCA9557_REG_CONFIG,
                         &data, 1);
        bHalI2C_MemRead(b_pca9557_halif[i].i2c, b_pca9557_halif[i].dev_addr, PCA9557_REG_CONFIG,
                        &data, 1);
        b_log("PCA9557_REG_IN %x\r\n", data);
    }
    return 0;
}

bDRIVER_REG_INIT(b_pca9557_init);

/**
 * \}
 */

/**
 * \}
 */

/**
 * \}
 */

/************************ Copyright (c) 2020 Bean *****END OF FILE****/
